package com.ruoyi.refund.controller;

import com.alibaba.fastjson.JSON;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.check.CheckEmptyUtil;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.utils.random.RandomUtils;
import com.ruoyi.order.domain.TechnicianItemOrder;
import com.ruoyi.order.mapper.TechnicianItemOrderMapper;
import com.ruoyi.order.mapper.UserItemOrderMapper;
import com.ruoyi.pay.refund.wx.util.WXRefundUtil;
import com.ruoyi.pay.refund.wx.vo.WeChatRefundReturnVO;
import com.ruoyi.pay.refund.wx.vo.WeChatRefundVO;
import com.ruoyi.pay.refund.zfb.util.ZFBRefundUtil;
import com.ruoyi.refund.domain.RefundOrder;
import com.ruoyi.refund.service.IRefundOrderService;
import com.ruoyi.refund.vo.AgreeRefund;
import com.ruoyi.refund.vo.RefuseRefundVo;
import com.ruoyi.user.domain.UserConsumeDetail;
import com.ruoyi.user.mapper.UserConsumeDetailMapper;
import com.ruoyi.user.mapper.UserMapper;
import com.ruoyi.util.voice.VoiceUtil;
import com.ruoyi.util.voice.vo.request.MiddleNumberUnbindVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.List;

/**
 * 退款订单Controller
 *
 * @author ruoyi
 * @date 2025-04-09
 */
@Slf4j
@RestController
@RequestMapping("/refundOrder/refundOrder")
public class RefundOrderController extends BaseController {
    @Autowired
    private IRefundOrderService refundOrderService;
    @Resource
    private TechnicianItemOrderMapper technicianItemOrderMapper;
    @Resource
    private UserItemOrderMapper userItemOrderMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private UserConsumeDetailMapper userConsumeDetailMapper;
    @Resource
    private WXRefundUtil wxRefundUtil;
    @Resource
    private ZFBRefundUtil zfbRefundUtil;
    @Resource
    private VoiceUtil voiceUtil;

    /**
     * 查询退款订单列表
     */
    @PreAuthorize("@ss.hasPermi('refundOrder:refundOrder:list')")
    @GetMapping("/list")
    public TableDataInfo list(RefundOrder refundOrder) {
        startPage();
        List<RefundOrder> list = refundOrderService.selectRefundOrderList(refundOrder);
        if (!CheckEmptyUtil.isEmpty(list)) {
            for (RefundOrder order : list) {
                String userName = technicianItemOrderMapper.selectUserName(order.getUserId());
                order.setUserName(CheckEmptyUtil.isEmpty(userName) ? "" : userName);
                String tName = technicianItemOrderMapper.selectTName(order.getTid());
                order.setTName(CheckEmptyUtil.isEmpty(tName) ? "" : tName);
            }
        }
        return getDataTable(list);
    }

    /**
     * 导出退款订单列表
     */
    @PreAuthorize("@ss.hasPermi('refundOrder:refundOrder:export')")
    @Log(title = "退款订单", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, RefundOrder refundOrder) {
        List<RefundOrder> list = refundOrderService.selectRefundOrderList(refundOrder);
        if (!CheckEmptyUtil.isEmpty(list)) {
            for (RefundOrder order : list) {
                String userName = technicianItemOrderMapper.selectUserName(order.getUserId());
                order.setUserName(CheckEmptyUtil.isEmpty(userName) ? "" : userName);
                String tName = technicianItemOrderMapper.selectTName(order.getTid());
                order.setTName(CheckEmptyUtil.isEmpty(tName) ? "" : tName);
            }
        }
        ExcelUtil<RefundOrder> util = new ExcelUtil<RefundOrder>(RefundOrder.class);
        util.exportExcel(response, list, "退款订单数据");
    }

    /**
     * 获取退款订单详细信息
     */
    @PreAuthorize("@ss.hasPermi('refundOrder:refundOrder:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        RefundOrder refundOrder = refundOrderService.selectRefundOrderById(id);
        if (!CheckEmptyUtil.isEmpty(refundOrder)) {

            String userName = technicianItemOrderMapper.selectUserName(refundOrder.getUserId());
            refundOrder.setUserName(CheckEmptyUtil.isEmpty(userName) ? "" : userName);
            String tName = technicianItemOrderMapper.selectTName(refundOrder.getTid());
            refundOrder.setTName(CheckEmptyUtil.isEmpty(tName) ? "" : tName);
            String userTel = technicianItemOrderMapper.selectUserTel(refundOrder.getUserId());
            refundOrder.setUserTel(CheckEmptyUtil.isEmpty(userTel) ? "" : userTel);
            String tTel = technicianItemOrderMapper.selectTTel(refundOrder.getTid());
            refundOrder.setTechnicianTel(CheckEmptyUtil.isEmpty(tTel) ? "" : tTel);
            String tAvatar = technicianItemOrderMapper.selectTAvatar(refundOrder.getTid());
            refundOrder.setTechnicianAvatar(CheckEmptyUtil.isEmpty(tAvatar) ? "" : tAvatar);
            TechnicianItemOrder technicianItemOrder = technicianItemOrderMapper.selectOne(refundOrder.getOrderNo());
            if (!CheckEmptyUtil.isEmpty(technicianItemOrder)) {
                refundOrder.setModeTravel(technicianItemOrder.getModeTravel());
                refundOrder.setDistance(technicianItemOrder.getDistance());
                refundOrder.setAddressDetail(technicianItemOrder.getAddressDetail());
            }
        }
        return success(refundOrder);
    }

    /**
     * 新增退款订单
     */
    @PreAuthorize("@ss.hasPermi('refundOrder:refundOrder:add')")
    @Log(title = "退款订单", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody RefundOrder refundOrder) {
        return toAjax(refundOrderService.insertRefundOrder(refundOrder));
    }


    /**
     * 同意退款
     */
    @PreAuthorize("@ss.hasPermi('refundOrder:refundOrder:add')")
    @Log(title = "退款订单", businessType = BusinessType.INSERT)
    @PostMapping("agreeRefund")
    @Transactional(rollbackFor = RuntimeException.class)
    public AjaxResult agreeRefund(@RequestBody AgreeRefund agreeRefund) throws Exception {
        RefundOrder refundOrder = refundOrderService.selectRefundOrderById(agreeRefund.getId());
        if (CheckEmptyUtil.isEmpty(refundOrder)) {
            throw new RuntimeException("订单不存在");
        }
        String refundOrderNo = RandomUtils.getOrderNo();
        TechnicianItemOrder technicianItemOrder = technicianItemOrderMapper.selectOne(refundOrder.getOrderNo());
        BigDecimal userRefundTotalPrice = agreeRefund.getRefundItemPrice().add(agreeRefund.getRefundCarPrice());
       if (userRefundTotalPrice.compareTo(BigDecimal.ZERO)>0){
           if ("BALANCE".equals(refundOrder.getPayType())) {
               //余额
               //修改余额
               Integer addBalance = userMapper.addBalance(refundOrder.getUserId(), userRefundTotalPrice);
               if (addBalance == 0) {
                   throw new RuntimeException("余额退款失败");
               }
               //修改记录
               UserConsumeDetail userConsumeDetail = new UserConsumeDetail();
               userConsumeDetail.setOrderNo(refundOrder.getOrderNo());
               userConsumeDetail.setUserId(refundOrder.getUserId());
               userConsumeDetail.setConsumptionPrice(userRefundTotalPrice);
               userConsumeDetail.setConsumptionType("REFUND");
               userConsumeDetail.setConsumptionDescribe(refundOrder.getItemName() + "项目退款");
               userConsumeDetailMapper.insertUserConsumeDetail(userConsumeDetail);
           } else if ("WX".equals(refundOrder.getPayType())) {
               BigDecimal totalPrice = technicianItemOrder.getOrderTotalPrice();
               WeChatRefundVO refundVO = new WeChatRefundVO();
               refundVO.setOut_refund_no(refundOrderNo);
               refundVO.setOut_trade_no(refundOrder.getOrderNo());
               WeChatRefundVO.amount amount = refundVO.new amount();
               amount.setTotal(totalPrice.multiply(new BigDecimal(100)).intValue());
               amount.setRefund(userRefundTotalPrice.multiply(new BigDecimal(100)).intValue());
               refundVO.setAmount(amount);
               log.info("退款入参:{}", JSON.toJSONString(refundVO));
               WeChatRefundReturnVO weChatRefundReturnVO = wxRefundUtil.refundOrder(refundVO);
               log.info("退款结果:{}", JSON.toJSONString(weChatRefundReturnVO));
               if (!"SUCCESS".equals(weChatRefundReturnVO.getStatus()) && !"PROCESSING".equals(weChatRefundReturnVO.getStatus())) {
                   throw new RuntimeException("微信退款失败");
               }
           } else if ("ZFB".equals(refundOrder.getPayType())) {
               zfbRefundUtil.refund(refundOrder.getOrderNo(), refundOrder.getOrderNo(), userRefundTotalPrice.toString(), refundOrder.getItemName() + "项目退款");
           } else {
               throw new RuntimeException("支付类型错误");
           }
       }

        //修改技师收入
        technicianItemOrderMapper.updateTechnicianIncome(refundOrder.getOrderNo(), agreeRefund.getTechnicianGetPrice());
        //修改订单状态
        technicianItemOrderMapper.updateOrderStatus(refundOrder.getOrderNo(), 12);
        userItemOrderMapper.updateOrderStatus(refundOrder.getOrderNo(), 12);
        //还原用户优惠券
        if (technicianItemOrder.getIsUserCoupon() == 1) {
            technicianItemOrderMapper.updateUserCouponStatus(technicianItemOrder.getUserCouponId());
        }
        String tTel = technicianItemOrderMapper.selectTTel(technicianItemOrder.getTid());
        //解绑技师与用户的号码
        MiddleNumberUnbindVo middleNumberUnbindVo = new MiddleNumberUnbindVo();
        middleNumberUnbindVo.setBindNumberA(tTel);
        middleNumberUnbindVo.setBindNumberB(technicianItemOrder.getAddressTel());
        voiceUtil.middleNumberUnbind(middleNumberUnbindVo);

        refundOrder.setCanRefundItemPrice(agreeRefund.getRefundItemPrice());
        refundOrder.setCanRefundFarePrice(agreeRefund.getRefundCarPrice());
        refundOrder.setCanRefundPrice(userRefundTotalPrice);
        refundOrder.setTechnicianGet(agreeRefund.getTechnicianGetPrice());
        refundOrder.setAuditStatus(1);
        return toAjax(refundOrderService.updateRefundOrder(refundOrder));
    }

    /**
     * 拒绝退款
     */
    @PreAuthorize("@ss.hasPermi('refundOrder:refundOrder:add')")
    @Log(title = "退款订单", businessType = BusinessType.INSERT)
    @PostMapping("refuseRefund")
    @Transactional(rollbackFor = RuntimeException.class)
    public AjaxResult refuseRefund(@RequestBody RefuseRefundVo refundVo) throws Exception {
        RefundOrder refundOrder = refundOrderService.selectRefundOrderById(refundVo.getId());
        if (CheckEmptyUtil.isEmpty(refundOrder)) {
            throw new RuntimeException("订单不存在");
        }
        technicianItemOrderMapper.updateOrderStatus(refundOrder.getOrderNo(), 13);
        userItemOrderMapper.updateOrderStatus(refundOrder.getOrderNo(), 13);
        refundOrder.setAuditStatus(2);
        refundOrder.setFalseReason(refundVo.getRefuseReason());
        return toAjax(refundOrderService.updateRefundOrder(refundOrder));
    }

    /**
     * 修改退款订单
     */
    @PreAuthorize("@ss.hasPermi('refundOrder:refundOrder:edit')")
    @Log(title = "退款订单", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody RefundOrder refundOrder) {
        return toAjax(refundOrderService.updateRefundOrder(refundOrder));
    }

    /**
     * 删除退款订单
     */
    @PreAuthorize("@ss.hasPermi('refundOrder:refundOrder:remove')")
    @Log(title = "退款订单", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(refundOrderService.deleteRefundOrderByIds(ids));
    }
}
